package org.timemanager.view;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;

/**
 * it uses opencsv, http://sourceforge.net/projects/opencsv/
 * another libs
 * http://kasparov.skife.org/csv/
 * http://commons.apache.org/proper/commons-csv/
 * @author Dereky
 * 2013-6-14
 *
 */
public class CSVExchange extends DataExchange {
	
	public CSVExchange(Context context) {
		super(context, "csv");
	}

	@Override
	public boolean save(String filename) {
		List<String[]> dataList = new ArrayList<String[]>();
		Cursor cursor = null;
		
		dataList.add(new String[]{TABLE_NUMBER});
		dataList.add(new String[]{Integer.toString(DatabaseTool.TABLE_NUMBER)});
		
		dataList.add(new String[]{TABLE_NAME, TABLE_ROWS});
		dataList.add(new String[]{DatabaseTool.CATEGORIES, Integer.toString(databaseTool.getCategoriesTotalNumber())});
		dataList.add(new String[]{DatabaseTool.EVENTS, Integer.toString(databaseTool.getEventsTotalNumber())});
		dataList.add(new String[]{DatabaseTool.RECORDS, Integer.toString(databaseTool.getRecordsTotalNumber())});
		
		dataList.add(new String[]{DatabaseTool.Category.ID, DatabaseTool.Category.NAME});
		cursor = databaseTool.getCategories();
		while(cursor.moveToNext()){
			dataList.add(new String[]{cursor.getString(0), changeCode(cursor.getString(1))});
		}
		cursor.close();
		
		dataList.add(new String[]{DatabaseTool.Event.ID, DatabaseTool.Event.NAME,
				DatabaseTool.Event.CATEGORY_ID, DatabaseTool.Event.WARN,
				DatabaseTool.Event.NOTE, DatabaseTool.Event.USED});
		cursor = databaseTool.getEvents();
		while(cursor.moveToNext()){
			dataList.add(new String[]{cursor.getString(0), changeCode(cursor.getString(1)),
					cursor.getString(2), cursor.getString(3),
					changeCode(cursor.getString(4)), cursor.getString(5)});
		}
		cursor.close();
		
		dataList.add(new String[]{DatabaseTool.Record.ID, DatabaseTool.Record.EVENT_ID,
				DatabaseTool.Record.START_TIME});
		cursor = databaseTool.getRecords();
		while(cursor.moveToNext()){
			dataList.add(new String[]{cursor.getString(0), cursor.getString(1),
					cursor.getString(2)});
		}
		cursor.close();

		try {
			StringWriter sw = new StringWriter();
			CSVWriter csvWriter = new CSVWriter(sw);
			csvWriter.writeAll(dataList);
			
//			File file = new File(filename);
//			if(!file.exists()){
//				file.createNewFile();
//			}
			FileWriter fileWriter = new FileWriter(filename);
			fileWriter.write(sw.toString());
			fileWriter.close();
			
			csvWriter.close();
			sw.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}

	@Override
	public boolean restore(String filename) {
		int lineNo = 0;
		int categoryRows = 0, eventRows = 0, recordRows = 0;
		String [] row;
		List<String[]> dataList = new ArrayList<String[]>();
		CSVReader reader = null;
		try {
			reader = new CSVReader(new FileReader(filename));
			while ((row = reader.readNext()) != null) {
				if(lineNo < 1){
					if(!compareStringArray(row, new String[]{TABLE_NUMBER})){
						return false;
					}
				}
				else if(lineNo < 2){
					if(!compareStringArray(row, new String[]{Integer.toString(DatabaseTool.TABLE_NUMBER)})){
						return false;
					}
				}
				else if(lineNo < 3){
					if(!compareStringArray(row, new String[]{TABLE_NAME, TABLE_ROWS})){
						return false;
					}
				}
				else if(lineNo < 4){
					if(!DatabaseTool.CATEGORIES.equals(row[0])){
						return false;
					}
					try {
						categoryRows = Integer.parseInt(row[1]);
					} catch (NumberFormatException e) {
						return false;
					}
				}
				else if(lineNo < 5){
					if(!DatabaseTool.EVENTS.equals(row[0])){
						return false;
					}
					try {
						eventRows = Integer.parseInt(row[1]);
					} catch (NumberFormatException e) {
						return false;
					}
				}
				else if(lineNo < 6){
					if(!DatabaseTool.RECORDS.equals(row[0])){
						return false;
					}
					try {
						recordRows = Integer.parseInt(row[1]);
					} catch (NumberFormatException e) {
						return false;
					}
				}
				else if(lineNo < 7){
					if(!compareStringArray(row, new String[]{DatabaseTool.Category.ID, DatabaseTool.Category.NAME})){
						return false;
					}
					dataList.clear();
				}
				else if(lineNo < 7+categoryRows){
					dataList.add(row);
					if(lineNo == 6+categoryRows){
						databaseTool.deleteCategories();
						if(!databaseTool.insertCategoryBatch(dataList)){
							return false;
						}
					}
				}
				else if(lineNo < 8+categoryRows){
					if(!compareStringArray(row, new String[]{DatabaseTool.Event.ID, DatabaseTool.Event.NAME,
							DatabaseTool.Event.CATEGORY_ID, DatabaseTool.Event.WARN,
							DatabaseTool.Event.NOTE, DatabaseTool.Event.USED})){
						return false;
					}
					dataList.clear();
				}
				else if(lineNo < 8+categoryRows+eventRows){
					dataList.add(row);
					if(lineNo == 7+categoryRows+eventRows){
						databaseTool.deleteEvents();
						if(!databaseTool.insertEventBatch(dataList)){
							return false;
						}
					}
				}
				else if(lineNo < 9+categoryRows+eventRows){
					if(!compareStringArray(row, new String[]{DatabaseTool.Record.ID, DatabaseTool.Record.EVENT_ID,
							DatabaseTool.Record.START_TIME})){
						return false;
					}
					dataList.clear();
				}
				else if(lineNo < 9+categoryRows+eventRows+recordRows){
					dataList.add(row);
					if(lineNo == 8+categoryRows+eventRows+recordRows){
						databaseTool.deleteRecords();
						if(!databaseTool.insertRecordBatch(dataList)){
							return false;
						}
					}
				}else {
					return false;
				}
				lineNo++;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally{
			if(reader!=null){
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return true;
	}

}
